package com.gitee.wsl.mathematics.algebraic

import com.gitee.wsl.mathematics.algebraic.Ring.Companion.optimizedPower
import com.gitee.wsl.mathematics.algebraic.number.NumericAlgebra
import com.gitee.wsl.mathematics.algebraic.number.ScaleOperations


/**
 * Represents field i.e., algebraic structure with three operations: associative, commutative addition and
 * multiplication, and division.
 *
 * **This interface differs from the eponymous mathematical definition: fields in KMath
 * also support associative multiplication by scalar.**
 *
 * @param T the type of the field element.
 */
 interface Field<T> : Ring<T>, FieldOps<T>, ScaleOperations<T>, NumericAlgebra<T> {
    override fun number(value: Number): T = scale(one, value.toDouble())

     fun power(arg: T, pow: Int): T = optimizedPower(arg, pow)

     companion object{
        /**
         * Raises [arg] to the integer power [exponent].
         *
         * Special case: 0 ^ 0 is 1.
         *
         * @receiver the algebra to provide multiplication and division.
         * @param arg the base.
         * @param exponent the exponent.
         * @return the base raised to the power.
         * @author Iaroslav Postovalov, Evgeniy Zhelenskiy
         */
        private fun <T> Field<T>.optimizedPower(arg: T, exponent: Int): T = when {
            exponent < 0 -> one / (this as Ring<T>).optimizedPower(arg, if (exponent == Int.MIN_VALUE) Int.MAX_VALUE.toUInt().inc() else (-exponent).toUInt())
            else -> (this as Ring<T>).optimizedPower(arg, exponent.toUInt())
        }
    }
}